package server.core.dao;

import java.io.*;
import java.util.HashMap;

import server.core.base.EntityBase;
import server.core.dao.DaoFactory.daoType;

/**
 * @author user
 *
 */
public class FileDAO extends MemoryDAO {
	private static final daoType DAO_TYPE = daoType.FILE;
	
	private FileDAO() {
	}

	private static class SingletonHolder {
		public static final FileDAO instance = new FileDAO();
	}

	public static FileDAO getInstance() {
		return SingletonHolder.instance;
	}

	@Override
	public HashMap<Long,? extends EntityBase> getEntityMap(Class<? extends EntityBase> entityClass){
		readHashMap(entityClass);
		return INSTANCE.getEntityMap(entityClass);
	}
	
	@Override
	public boolean setEntityMap(Class<? extends EntityBase> entityClass,HashMap<Long,? extends EntityBase> hashmap1){
		if(true==INSTANCE.setEntityMap(entityClass, hashmap1)){
			try {
				writeHashMap(entityClass);
				return true;
				} catch (Throwable e) {
					e.printStackTrace();
					return false;
				}
			}
		else
			return false;
	}
	
	@Override
	public long saveObject(EntityBase entity) {
		INSTANCE.saveObject(entity);
		writeHashMap(entity.getClass());
		return entity.getId();
	}

	@Override
	public boolean deleteObject(Class<? extends EntityBase> entityClass, long id) {
		INSTANCE.deleteObject(entityClass, this.getObject(entityClass, id).getId());
		try {
			this.writeHashMap(entityClass);
			return true;
		} catch (Throwable e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public EntityBase getObject(Class<? extends EntityBase> entityClass, long id) {
		readHashMap(entityClass);
		return INSTANCE.getObject(entityClass, id);
	}

	@Override
	public daoType getDaoType() {
		getInstance();
		return DAO_TYPE;
	}
	
	
	/**Write HashMap into file `name of EntityBase`.bin
	 * @param class1
	 */
	public void writeHashMap(Class<? extends EntityBase> class1) {
		try(ObjectOutputStream out=
				new ObjectOutputStream(new FileOutputStream(class1.getSimpleName()+".bin"))) {
			File file=new File(class1.getSimpleName()+".bin");
			if(file.exists())
				file.delete();
			out.writeObject(INSTANCE.getEntityMap(class1));
		} catch(IOException e) {
			System.out.println("Some output error occurred!");
			e.printStackTrace();
		}
	}
	
	/**
	 * @param class1
	 */
	@SuppressWarnings("unchecked")
	public void readHashMap(Class<? extends EntityBase> class1) {
		try(ObjectInputStream in=
				new ObjectInputStream(new FileInputStream(class1.getSimpleName()+".bin"))){
			INSTANCE.setEntityMap(class1, (HashMap<Long,? extends EntityBase>) in.readObject());
		} catch(IOException e) {
		      System.out.println("Some input error occurred!");
		      e.printStackTrace();
		} catch(ClassNotFoundException e) {
		      System.out.println("Wrong object type");
		      e.printStackTrace();
		}
	}

}
